package cn.edu.neu.vmmigeval.cloud.entity;

import cn.edu.neu.vmmigeval.cloud.config.Migration;
import cn.edu.neu.vmmigeval.cloud.policy.VmAllocation;

import java.util.ArrayList;
import java.util.List;

/**
 * The data center entity.
 *
 * Created by yfwz100 on 16/2/25.
 */
public class DataCenter {

    private String scale;

    private String workloadType;

    public VmAllocation vmAllocation;

    public List<Host> hosts;

    public List<Migration> migrationings = new ArrayList<Migration>();

    public List<Migration> migrationFinished = new ArrayList<Migration>();

    public DataCenter(){

    }
    public DataCenter(VmAllocation vmAllocation) {
        super();
        this.vmAllocation = vmAllocation;
    }

    public void updateAllMigration(){

        //System.out.println("进行该周期的迁移任务的状态的刷新！");
        for(int i=0;i<migrationings.size();i++){
            Migration migration = migrationings.get(i);

            //	int currentClock = migration.getNowClock()+1;
            //	if(currentClock>=migration.getClocks()){

            Host host = migration.getSrcHost();
            int totalCpus = 0 ;
            int totalRam = 0 ;
            int totalBw = 0 ;
            int totalDisk = 0;
            List<Vm> vms = migration.getVms();
            for(Vm vm:vms){
                vm.setInMigration(false);
                totalCpus+=vm.getCurrentCpu();
                totalRam+=vm.getCurrentRam();
                totalBw+=vm.getCurrentBw();
                totalDisk+=vm.getCurrentDisk();
            }
            host.getVmList().removeAll(vms);
            host.setCurrentCpu(host.getCurrentCpu()-totalCpus);
            host.setCurrentRam(host.getCurrentRam()-totalRam);
            host.setCurrentBw(host.getCurrentBw()-totalBw);
            host.setCurrentDisk(host.getCurrentDisk()-totalDisk);

            host.setMigration(false);
            host.setMigrationIn(0);
            host.setActive(0);

            if(host.getVmList().size()==0){
                //关机
                host.setActive(1);
            }
            //datacenter.updateHostInHostList(host);

            Host destHost = migration.getDestHost();
            destHost.getVmList().addAll(vms);
            destHost.setMigration(false);
            destHost.setMigrationIn(0);
            destHost.setActive(0);
            migration.setEnd(true);
            //datacenter.updateHostInHostList(destHost);

            migrationings.remove(migration);
            migrationFinished.add(migration);

            //System.out.println("源节点："+host.getId()+" 到目的节点"+destHost.getId()+"的迁移已经完成了");
			/*
			}else{
				migration.setNowClock(migration.getNowClock()+1);
			}*/
        }
    }

    public void updateHostsProcessing(int clock){

        if(hosts!=null&&hosts.size()!=0){

            for (Host host : hosts) {
                if(host.getActive()==0){
                    List<Vm> vms = host.getVmList();
                    //关机状态
                    if(vms==null||vms.size()==0){
                        host.setCurrentCpu(0);
                        host.setCurrentBw(0);
                        host.setCurrentDisk(0);
                        host.setCurrentRam(0);
                        host.setActive(1);
                        host.setMigration(false);
                        host.setMigrationIn(0);
                    }else{

                        int currentCpu = 0 ;
                        int currentRam = 0 ;
                        int currentBw = 0 ;
                        int currentDisk = 0 ;

                        for (Vm vm : vms) {
                            currentCpu+=vm.getCurrentCpu();
                            currentRam+=vm.getCurrentRam();
                            currentBw+=vm.getCurrentBw();
                            currentDisk+=vm.getCurrentDisk();
                        }
                        //对迁移的
                        if(host.getMigrationIn()==2){

                            //int cpu = (int)(currentCpu+host.getTotalCpu());
                            int cpu =(int)(host.getTotalCpu()*0.1+currentCpu);
                            int ram =(int)(host.getTotalRam()*0.1+currentRam);
                            int bw =(int)(host.getTotalBw()*0.1+currentBw);
                            int disk =(int)(host.getTotalDisk()*0.1+currentDisk);

                            host.setCurrentCpu(cpu>host.getTotalCpu()?host.getTotalCpu():cpu);
                            host.setCurrentRam(ram>host.getTotalRam()?host.getTotalRam():ram);
                            host.setCurrentBw(bw>host.getTotalBw()?host.getTotalBw():bw);
                            host.setCurrentDisk(disk>host.getTotalDisk()?host.getTotalDisk():disk);

                        }else{
                            host.setCurrentCpu(currentCpu);
                            host.setCurrentRam(currentRam);
                            host.setCurrentBw(currentBw);
                            host.setCurrentDisk(currentDisk);
                        }
                    }

                    List<Double> uh = host.getUtilizationHistory();
                    if(uh.size()>=15){
                        uh.remove(0);
                        //uh.add((double)host.getCurrentCpu()/host.getTotalCpu());
                    }
                    uh.add((double)host.getCurrentCpu()/host.getTotalCpu());
                    host.setUtilizationHistory(uh);
                }

                else{
                    host.setCurrentBw(0);
                    host.setCurrentCpu(0);
                    host.setCurrentDisk(0);
                    host.setCurrentRam(0);
                    host.setMigration(false);
                    host.setActive(1);
                    host.setMigrationIn(0);
                }
            }
        }
    }

    public List<Host> getHosts() {
        return hosts;
    }

    public void setHosts(List<Host> hosts) {
        this.hosts = hosts;
    }

    public VmAllocation getVmAllocation() {
        return vmAllocation;
    }

    public void setVmAllocation(VmAllocation vmAllocation) {
        this.vmAllocation = vmAllocation;
    }
    public List<Migration> getMigrationings() {
        return migrationings;
    }
    public void setMigrationings(List<Migration> migrationings) {
        this.migrationings = migrationings;
    }
    public List<Migration> getMigrationFinished() {
        return migrationFinished;
    }
    public void setMigrationFinished(List<Migration> migrationFinished) {
        this.migrationFinished = migrationFinished;
    }
    public String getScale() {
        return scale;
    }
    public void setScale(String scale) {
        this.scale = scale;
    }
    public String getWorkloadType() {
        return workloadType;
    }
    public void setWorkloadType(String workloadType) {
        this.workloadType = workloadType;
    }
}
